# To change this template, choose Tools | Templates
# and open the template in the editor.
from math import log
from math import exp
from math import sqrt
from random import gauss

__author__="e019657"
__date__ ="$22-Dec-2011 11:23:19$"

class PathCreator:    
    drifts = []
    stdDevs = []
    fixingDays = []

    def __init__(self, spotIni, fixingDays, r, vol, base):
        self.fixingDays = fixingDays
        fixingDaysInYearFractionFormat = map(lambda x: float(x)/base, self.fixingDays)
        divRate = 0
        self.logSpot = log(spotIni)

        variance = self.integralsq(0, fixingDaysInYearFractionFormat[0], vol)
        self.drifts.append(self.integral(0,fixingDaysInYearFractionFormat[0], r) -  self.integral (0, fixingDaysInYearFractionFormat[0], divRate) - 0.5 * variance)
        self.stdDevs.append( sqrt(variance))
        #print "Step: %s Day: %s Rate: %s Vol: %s " % (0, self.fixingDays[0], self.drifts[0], self.stdDevs[0])

        for i in range (1, len(fixingDaysInYearFractionFormat)):
            varianceInStep = self.integralsq(fixingDaysInYearFractionFormat[i-1], fixingDaysInYearFractionFormat[i], vol)
            self.drifts.append( self.integral(fixingDaysInYearFractionFormat[i-1], fixingDaysInYearFractionFormat[i], r) - self.integral(fixingDaysInYearFractionFormat[i-1], fixingDaysInYearFractionFormat[i], divRate) - 0.5* varianceInStep)
            self.stdDevs.append(sqrt(varianceInStep))
            #print "Step: %s Day: %s Rate: %s Drift: %s Vol: %s " % (i, self.fixingDays[i], self.integralsq(fixingDaysInYearFractionFormat[i-1], fixingDaysInYearFractionFormat[i], vol), self.drifts[i], self.stdDevs[i])
            

    def get_one_path (self):
        spotValues = {}
        currentLogSpot = self.logSpot
        for i in range (0, len(self.fixingDays)):
            currentLogSpot +=self.drifts[i]
            currentLogSpot += self.stdDevs[i]*gauss(0,1)
            spotValues[self.fixingDays[i]] = exp(currentLogSpot)
        return spotValues

    def get_spot_values(self):
        return self.spotValues

    def get_drifts (self):
        return self.drifts
    
    def get_std_devs(self):
        return self.stdDevs

    def integral(self, n1, n2, constant):
        return (n2-n1)*constant

    def integralsq(self, n1, n2, constant):
        return (n2-n1)*constant*constant

